package com.restaurant.springboot.controller;

import com.restaurant.springboot.annotation.MayHaveBug;
import com.restaurant.springboot.entity.UserEntity;
import com.restaurant.springboot.service.UserService;
import com.restaurant.springboot.utils.Constant;
import com.restaurant.springboot.utils.JwtUtil;
import com.restaurant.springboot.utils.RespCode;
import com.restaurant.springboot.utils.RespEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.sql.Timestamp;


@RestController
@RequestMapping("api/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    JwtUtil jwtUtil;


    /**
     * 存在bug，如果上传的UserEntity中某些字段是空的，那么就会被设置为空
     * 应该先检测用户存在性
     * 然后单独修改用户的最近登录时间
     *
     * @param session 上下文
     * @param request 请求
     * @return 处理结果
     * @throws Exception
     */
    @PostMapping("")
    @MayHaveBug
    public RespEntity login(@RequestParam("code") String code, HttpSession session, HttpServletRequest request) throws Exception {
        String openId = userService.getOpenId(code);
        if (openId == null) {
            return new RespEntity(
                    RespCode.ERROR,
                    "无法获取openId",
                    null
            );
        }
        UserEntity user = userService.getUser(openId);
        if (user == null) {
            return new RespEntity(
                    RespCode.NO_REGISTER
            );
        }
        Timestamp time = new Timestamp(System.currentTimeMillis());
        user.setLastTime(time);
        if (userService.userIsExit(user.getOpenId())) {
            userService.updateUser(user);
        } else {

        }
        if (userService.updateUser(user)) {
            String jwt = saveToken(user, session, request);
            return new RespEntity(RespCode.SUCCESS, "login success", jwt);
        } else {
            return new RespEntity(RespCode.ERROR, "login fail");
        }
    }

    /**
     * @param user    用户
     * @param session 上下文
     * @param request 请求
     * @return 结果
     * @throws Exception 错误
     */
    private String saveToken(
            @RequestBody UserEntity user,
            HttpSession session,
            HttpServletRequest request) throws Exception {
        //通过userId和user-agent产生token
        session.setAttribute("user", user);
        String userAgent = request.getHeader("User-Agent");
        session.setAttribute("userAgent", userAgent);
        int userId = user.getId();
        String subject = JwtUtil.generalSubject(userId, userAgent);
        return jwtUtil.createJWT(subject, Constant.JWT_TTL);
    }

    /**
     * 获取用户的信息
     *
     * @param userId 用户id
     * @return 返回用户信息
     */
    @GetMapping("/{userId}/info")
    public RespEntity getUser(@PathVariable int userId) {
        UserEntity user = userService.getUserById(userId);
        if (user == null) {
            return new RespEntity(
                    RespCode.NO_REGISTER
            );
        } else {
            return new RespEntity(
                    RespCode.SUCCESS
            );
        }
    }

    /**
     * 用户注册
     *
     * @param code        微信临时凭证
     * @param nickName    昵称
     * @param url         图片链接
     * @param httpSession 上下文
     * @return 结果
     */
    @PostMapping("/register")
    public RespEntity register(
            @RequestParam("code") String code,
            @RequestParam("nickName") String nickName,
            @RequestParam("url") String url,
            HttpSession httpSession) {
        UserEntity user = (UserEntity) httpSession.getAttribute("user");
        if (user != null) {
            return new RespEntity(
                    RespCode.ERROR,
                    "你已经注册，无需重新注册",
                    null
            );
        }
        if (userService.registerUser(code, nickName, url)) {
            new RespEntity(
                    RespCode.SUCCESS
            );
        } else {
            new RespEntity(
                    RespCode.ERROR
            );
        }
        return null;
    }
}
